package com.ruoyi.web.controller.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

/**
 * RedisUtilsTwo 对应的Controller
 * 所有请求参数均通过请求体(JSON)传递
 */
@RestController
@RequestMapping("/api/redis-two")
public class RedisTwoController {

    @Autowired
    private RedisUtilsTwo redisUtilsTwo;

    // -------------------------- 存储数据接口 --------------------------

    /**
     * 批量存储数据到Redis
     * 请求体示例：
     * {
     *   "keyPrefix": "user",          // Redis键前缀
     *   "indexKey": "user:index",     // 索引键
     *   "dataList": [                 // 要存储的数据列表（JSON对象集合）
     *     {"id": "1001", "name": "张三", "age": 22, "status": 1},
     *     {"id": "1002", "name": "李四", "age": 28, "status": 0}
     *   ],
     *   "expireTime": 7200             // 过期时间（秒，默认3600）
     * }
     */
    @PostMapping("/store")
    public String storeData(@RequestBody StoreDTO storeDTO) {
        // 验证必要参数
        if (storeDTO.getKeyPrefix() == null || storeDTO.getIndexKey() == null) {
            return "参数错误：keyPrefix和indexKey不能为空";
        }
        if (storeDTO.getDataList() == null || storeDTO.getDataList().isEmpty()) {
            return "参数错误：dataList不能为空";
        }

        // 提取数据中的ID作为Redis键的后缀（支持Map类型数据）
        Function<Object, String> idExtractor = obj -> {
            if (obj instanceof Map) {
                // 从Map中获取"id"字段（确保数据中包含id）
                Object id = ((Map<?, ?>) obj).get("id");
                if (id != null) {
                    return id.toString();
                }
                // 若没有id字段，自动生成UUID作为键
                return UUID.randomUUID().toString();
            }
            // 非Map类型数据直接用toString作为键
            return obj.toString();
        };

        // 调用RedisUtilsTwo存储数据
        redisUtilsTwo.builder()
                .keyPrefix(storeDTO.getKeyPrefix())
                .indexKey(storeDTO.getIndexKey())
                .dataList(storeDTO.getDataList())
                .keyExtractor(idExtractor)
                .expireTime(storeDTO.getExpireTime() > 0 ? storeDTO.getExpireTime() : 3600) // 默认3600秒
                .store();

        return "数据存储成功，共存储 " + storeDTO.getDataList().size() + " 条记录";
    }

    // -------------------------- 查询数据接口 --------------------------

    /**
     * 分页查询数据（支持多条件过滤和排序）
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "indexKey": "user:index",
     *   "pageNum": 1,
     *   "pageSize": 10,
     *   "sortField": "age",       // 排序字段（可选）
     *   "isAscending": true,      // 是否升序（默认true）
     *   "conditions": {           // 查询条件（支持eq/ne/gt/lt/gte/lte）
     *     "age": {"gte": 18, "lte": 30},
     *     "status": {"eq": 1}
     *   }
     * }
     */
    @PostMapping("/page-query")
    public RedisUtilsTwo.PageResult<String> pageQuery(@RequestBody PageQueryDTO queryDTO) {
        // 验证必要参数
        if (queryDTO.getIndexKey() == null) {
            throw new IllegalArgumentException("参数错误：indexKey不能为空");
        }

        // 处理默认值
        int pageNum = queryDTO.getPageNum() < 1 ? 1 : queryDTO.getPageNum();
        int pageSize = queryDTO.getPageSize() < 1 ? 10 : queryDTO.getPageSize();

        // 调用RedisUtilsTwo分页查询
        return redisUtilsTwo.builder()
                .keyPrefix(queryDTO.getKeyPrefix()) // 可为null，查询时主要用indexKey
                .indexKey(queryDTO.getIndexKey())
                .pageQuery(pageNum, pageSize, queryDTO.getConditions(),
                        queryDTO.getSortField(), queryDTO.isAscending());
    }

    /**
     * 根据ID获取单个数据
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "id": "1001"
     * }
     */
    @PostMapping("/get-by-id")
    public String getById(@RequestBody GetByIdDTO getByIdDTO) {
        if (getByIdDTO.getKeyPrefix() == null || getByIdDTO.getId() == null) {
            return "参数错误：keyPrefix和id不能为空";
        }

        return redisUtilsTwo.builder()
                .keyPrefix(getByIdDTO.getKeyPrefix())
                .getById(getByIdDTO.getId());
    }

    /**
     * 批量根据ID获取数据
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "ids": ["1001", "1002", "1003"]
     * }
     */
    @PostMapping("/batch-get")
    public List<String> batchGet(@RequestBody BatchGetDTO batchGetDTO) {
        if (batchGetDTO.getKeyPrefix() == null || batchGetDTO.getIds() == null || batchGetDTO.getIds().isEmpty()) {
            return List.of("参数错误：keyPrefix和ids不能为空");
        }

        return redisUtilsTwo.builder()
                .keyPrefix(batchGetDTO.getKeyPrefix())
                .getByIds(batchGetDTO.getIds());
    }

    // -------------------------- 删除数据接口 --------------------------

    /**
     * 根据ID删除数据
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "indexKey": "user:index",
     *   "id": "1001"
     * }
     */
    @PostMapping("/delete-by-id")
    public String deleteById(@RequestBody DeleteByIdDTO deleteByIdDTO) {
        if (deleteByIdDTO.getKeyPrefix() == null || deleteByIdDTO.getIndexKey() == null || deleteByIdDTO.getId() == null) {
            return "参数错误：keyPrefix、indexKey和id不能为空";
        }

        redisUtilsTwo.builder()
                .keyPrefix(deleteByIdDTO.getKeyPrefix())
                .indexKey(deleteByIdDTO.getIndexKey())
                .delete(deleteByIdDTO.getId());

        return "ID为 " + deleteByIdDTO.getId() + " 的数据已删除";
    }

    /**
     * 批量删除数据
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "indexKey": "user:index",
     *   "ids": ["1001", "1002"]
     * }
     */
    @PostMapping("/batch-delete")
    public String batchDelete(@RequestBody BatchDeleteDTO batchDeleteDTO) {
        if (batchDeleteDTO.getKeyPrefix() == null || batchDeleteDTO.getIndexKey() == null
                || batchDeleteDTO.getIds() == null || batchDeleteDTO.getIds().isEmpty()) {
            return "参数错误：keyPrefix、indexKey和ids不能为空";
        }

        redisUtilsTwo.builder()
                .keyPrefix(batchDeleteDTO.getKeyPrefix())
                .indexKey(batchDeleteDTO.getIndexKey())
                .batchDelete(batchDeleteDTO.getIds());

        return "已批量删除 " + batchDeleteDTO.getIds().size() + " 条数据";
    }

    /**
     * 删除指定前缀的所有数据（谨慎使用）
     * 请求体示例：
     * {
     *   "keyPrefix": "user",
     *   "indexKey": "user:index"
     * }
     */
    @PostMapping("/delete-all")
    public String deleteAll(@RequestBody DeleteAllDTO deleteAllDTO) {
        if (deleteAllDTO.getKeyPrefix() == null || deleteAllDTO.getIndexKey() == null) {
            return "参数错误：keyPrefix和indexKey不能为空";
        }

        redisUtilsTwo.builder()
                .keyPrefix(deleteAllDTO.getKeyPrefix())
                .indexKey(deleteAllDTO.getIndexKey())
                .deleteAll();

        return "已删除 keyPrefix为 " + deleteAllDTO.getKeyPrefix() + " 的所有数据及索引";
    }


    /**
     * 存储数据的请求参数DTO
     */
    public static class StoreDTO {
        private String keyPrefix;
        private String indexKey;
        private List<Object> dataList; // 接收JSON对象列表（会被解析为Map）
        private long expireTime;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getIndexKey() { return indexKey; }
        public void setIndexKey(String indexKey) { this.indexKey = indexKey; }
        public List<Object> getDataList() { return dataList; }
        public void setDataList(List<Object> dataList) { this.dataList = dataList; }
        public long getExpireTime() { return expireTime; }
        public void setExpireTime(long expireTime) { this.expireTime = expireTime; }
    }

    /**
     * 分页查询的请求参数DTO
     */
    public static class PageQueryDTO {
        private String keyPrefix;
        private String indexKey;
        private int pageNum;
        private int pageSize;
        private String sortField;
        private boolean isAscending = true;
        private Map<String, Object> conditions;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getIndexKey() { return indexKey; }
        public void setIndexKey(String indexKey) { this.indexKey = indexKey; }
        public int getPageNum() { return pageNum; }
        public void setPageNum(int pageNum) { this.pageNum = pageNum; }
        public int getPageSize() { return pageSize; }
        public void setPageSize(int pageSize) { this.pageSize = pageSize; }
        public String getSortField() { return sortField; }
        public void setSortField(String sortField) { this.sortField = sortField; }
        public boolean isAscending() { return isAscending; }
        public void setAscending(boolean ascending) { isAscending = ascending; }
        public Map<String, Object> getConditions() { return conditions; }
        public void setConditions(Map<String, Object> conditions) { this.conditions = conditions; }
    }

    /**
     * 根据ID获取数据的请求参数DTO
     */
    public static class GetByIdDTO {
        private String keyPrefix;
        private String id;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
    }

    /**
     * 批量获取数据的请求参数DTO
     */
    public static class BatchGetDTO {
        private String keyPrefix;
        private List<String> ids;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
    }

    /**
     * 根据ID删除数据的请求参数DTO
     */
    public static class DeleteByIdDTO {
        private String keyPrefix;
        private String indexKey;
        private String id;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getIndexKey() { return indexKey; }
        public void setIndexKey(String indexKey) { this.indexKey = indexKey; }
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
    }

    /**
     * 批量删除数据的请求参数DTO
     */
    public static class BatchDeleteDTO {
        private String keyPrefix;
        private String indexKey;
        private List<String> ids;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getIndexKey() { return indexKey; }
        public void setIndexKey(String indexKey) { this.indexKey = indexKey; }
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
    }

    /**
     * 删除所有数据的请求参数DTO
     */
    public static class DeleteAllDTO {
        private String keyPrefix;
        private String indexKey;

        // Getter和Setter
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getIndexKey() { return indexKey; }
        public void setIndexKey(String indexKey) { this.indexKey = indexKey; }
    }
}
